package com.javasee.common.dbsharding;

import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.plugin.*;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.util.Objects;
import java.util.Properties;


@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class DbShardingMyBatisInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        BoundSql boundSql = statementHandler.getBoundSql();
        String sql = boundSql.getSql();
        DbshardingContext dbshardingContext = DbShardingContextHolder.get();


        //单库单表，未进行配置,dbshardingContext==null ,不进行sql的替换
        if(Objects.nonNull(dbshardingContext)){
            String newSql = sql.replaceAll(dbshardingContext.getTbName(), dbshardingContext.getRealTbName());
            Field field = boundSql.getClass().getDeclaredField("sql");
            field.setAccessible(true);
            field.set(boundSql, newSql);
        }

        Object result = null;
        try {
            result = invocation.proceed();
        } catch (Throwable e) {
            throw e;
        }
        return result;
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}
